package cn.itsource.service.impl;

import cn.itsource.exception.GlobalException;
import cn.itsource.mapper.ChargeRuleStartMapper;
import cn.itsource.pojo.bo.RuleStartBo;
import cn.itsource.pojo.domain.*;
import cn.itsource.pojo.dto.RuleStartDto;
import cn.itsource.pojo.dto.RuleWaitDto;
import cn.itsource.pojo.dto.SharingDto;
import cn.itsource.pojo.vo.SharingVo;
import cn.itsource.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * <p>
 * 计价规则-起步价 服务实现类
 * </p>
 *
 * @author beishan
 * @since 2024-04-10
 */
@Service
public class ChargeRuleStartServiceImpl extends ServiceImpl<ChargeRuleStartMapper, ChargeRuleStart> implements IChargeRuleStartService {

    @Autowired
    private IChargeRuleReturnService ruleReturnService;

    @Autowired
    private IChargeRuleWaitService waitService;

    @Autowired
    private IProfitsharingRuleBaseService ruleBaseService;

    @Autowired
    private IProfitsharingRuleCancelService ruleCancelService;

    @Autowired
    private IProfitsharingRuleComplainService ruleComplainService;
    /**
     * 平台抽成计价
     */
    @Override
    public SharingVo sharing(SharingDto sharingDto) {
        if (sharingDto == null) {
            throw new GlobalException("参数异常");
        }
        BigDecimal amount = sharingDto.getAmount();
        Integer cancel = sharingDto.getCancel();
        Integer complain = sharingDto.getComplain();

        //基础 平台抽成
        ProfitsharingRuleBase ruleBase = ruleBaseService.list().get(0);
        BigDecimal driverRatio = ruleBase.getDriverRatio();
        BigDecimal driverBase = amount.multiply(driverRatio);

        BigDecimal driverCancel = BigDecimal.ZERO;
        BigDecimal driverComplain = BigDecimal.ZERO;
        BigDecimal platformRate = BigDecimal.ZERO;
        BigDecimal driverRate = BigDecimal.ZERO;
        //司机订单取消数
        if (cancel != 0 ){
            ProfitsharingRuleCancel ruleCancel = ruleCancelService.getOne(new LambdaQueryWrapper<ProfitsharingRuleCancel>()
                    .le(ProfitsharingRuleCancel::getNumberFrom, cancel)
                    .ge(ProfitsharingRuleCancel::getNumberTo, cancel)
            );
            //司机订单取消扣除的金额
            driverCancel = amount.multiply(ruleCancel.getDriverRatioDeduct());
            //比例
            platformRate = ruleCancel.getDriverRatioDeduct();

        }


        //司机订单投诉数
        if (complain != 0 ){
            ProfitsharingRuleComplain ruleComplain = ruleComplainService.getOne(new LambdaQueryWrapper<ProfitsharingRuleComplain>()
                    .le(ProfitsharingRuleComplain::getNumberFrom, complain)
                    .ge(ProfitsharingRuleComplain::getNumberTo, complain)
            );
            //司机订单投诉扣除的金额
            driverComplain = amount.multiply(ruleComplain.getDriverRatioDeduct());
            //比例
            driverRate = ruleComplain.getDriverRatioDeduct();
        }


        //计算司机 被抽成后的金额
        BigDecimal driverRealAmount = driverBase.subtract(driverCancel).subtract(driverComplain);

        //平台分账金额
        BigDecimal platformAmount = amount.subtract(driverRealAmount);
        //平台分帐比例
        BigDecimal platform = driverRatio.add(platformRate).add(driverRate);
        //司机分账比例
        BigDecimal driver = new BigDecimal(1).subtract(platform);

        return new SharingVo(driver,platform,driverRealAmount,platformAmount);
    }

    /**
     * 等时计价
     * @param moreData
     * @return
     */
    @Override
    public RuleWaitDto ruleWait(Long moreData) {
        List<ChargeRuleWait> list = waitService.list();
        ChargeRuleWait wait = list.get(0);
        BigDecimal minuteAmount = wait.getExceedEveryMinuteAmount();
        if (moreData < wait.getFreeBaseWaitingMinute()) {
            return  null;
        }
        BigDecimal multiply = minuteAmount.multiply(BigDecimal.valueOf(moreData));
        RuleWaitDto ruleWaitDto = new RuleWaitDto();

        ruleWaitDto.setDecimal(multiply);
        ruleWaitDto.setFree_base_waiting_minute(wait.getFreeBaseWaitingMinute());
        ruleWaitDto.setExceed_every_minute_amount(minuteAmount);

        return ruleWaitDto;
    }



    /**
     * 计算 预付金额 和返程金额
     * @param ruleStartDto
     * @return
     */
    @Override
    public RuleStartBo ruleStartAdvance(RuleStartDto ruleStartDto) {
        RuleStartBo startBo = new RuleStartBo();
        BigDecimal startAmount = computeStart(ruleStartDto,startBo);
        BigDecimal returnAmount = computeReturn(ruleStartDto,startBo);
        startBo.setStart_advance(startAmount.add(returnAmount));
        startBo.setMileageAmount(startAmount);
        startBo.setReturnAmount(returnAmount);

        return startBo;
    }




    //计算返程费用
    public BigDecimal computeReturn(RuleStartDto ruleStartDto,RuleStartBo startBo) {
        //获取返程规则
        ChargeRuleReturn ruleReturn = ruleReturnService.list().get(0);
        //免费里程数
        BigDecimal freeBaseReturnMileage = ruleReturn.getFreeBaseReturnMileage();
        startBo.setFreeBaseReturnMileage(freeBaseReturnMileage);
        //超出免费里程的收费
        BigDecimal exceedEveryKmAmount = ruleReturn.getExceedEveryKmAmount();
        startBo.setExceedBaseReturnEveryKmAmount(exceedEveryKmAmount);

        BigDecimal mileage = ruleStartDto.getMileage();
        //比较是否超出免费里程数
        BigDecimal multiply = BigDecimal.ZERO;
        if (freeBaseReturnMileage.compareTo(mileage) < 0) {
            BigDecimal divide = mileage.divide(freeBaseReturnMileage);
            multiply = divide.multiply(exceedEveryKmAmount);

        }

        return multiply;
    }

    //计算基本里程金额
    public BigDecimal computeStart(RuleStartDto ruleStartDto,RuleStartBo startBo) {
        //获取时间的小时数
        Date startDate = ruleStartDto.getStartDate();
        BigDecimal mileage = ruleStartDto.getMileage();
        GregorianCalendar calendar = new GregorianCalendar ();
        calendar.setTime(startDate);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        //通过小时数来 获取对应的计价规则数据
        ChargeRuleStart ruleStart = super.getOne(new LambdaQueryWrapper<ChargeRuleStart>()
                .le(ChargeRuleStart::getHourStart, hour)
                .ge(ChargeRuleStart::getHourEnd, hour));
        //基础里程数
        BigDecimal baseMileage = ruleStart.getBaseMileage();
        startBo.setBaseMileage(baseMileage);
        //超出起步价每公里的价格
        BigDecimal exceedEveryKmAmount = ruleStart.getExceedEveryKmAmount();
        startBo.setExceedBaseMileageAmount(exceedEveryKmAmount);
        //起步价 价格
        BigDecimal amount = ruleStart.getAmount();
        startBo.setBaseMileageAmount(amount);
        if (mileage.compareTo(baseMileage) > 0){
            //里程数大于基础里程数
            BigDecimal subtract = mileage.subtract(baseMileage);
            BigDecimal multiply = subtract.multiply(exceedEveryKmAmount);

            return multiply.add(amount);
        }else {
            //里程数小于等于基础里程数
            return amount;
        }
    }

}
